package com.ellecity06.cwhiskymall.ui.live.player

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.SurfaceHolder
import android.view.View
import androidx.lifecycle.lifecycleScope
import com.aliyun.player.AliPlayer
import com.aliyun.player.AliPlayerFactory
import com.aliyun.player.IPlayer
import com.aliyun.player.bean.ErrorInfo
import com.aliyun.player.source.UrlSource
import com.ellecity06.common.base.BaseMvvmActivity
import com.ellecity06.common.ktx.isFoldExpandStatus
import com.ellecity06.common.ktx.load
import com.ellecity06.common.ktx.observeEvent
import com.ellecity06.common.utils.ToastUtils
import com.ellecity06.common.utils.appContext
import com.ellecity06.common.utils.gson
import com.ellecity06.common.utils.logD
import com.ellecity06.cwhiskymall.bean.push.PushTopGoodModel
import com.ellecity06.cwhiskymall.bean.response.LiveRoomResponse
import com.ellecity06.cwhiskymall.constant.BusConstants
import com.ellecity06.cwhiskymall.databinding.ActivityLivePlayerBinding
import com.ellecity06.cwhiskymall.timer.tickFlow
import com.ellecity06.cwhiskymall.ui.live.LiveViewModel
import com.ellecity06.cwhiskymall.ui.live.chat.ChatDialogFragment
import com.ellecity06.cwhiskymall.ui.live.chat.OnChatClickListener
import com.jeremyliao.liveeventbus.LiveEventBus
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay

/**
 * @author ellecity06
 * @time 2024/11/28 15:47
 * @des 播放直播的页面
 */
class LivePlayerActivity : BaseMvvmActivity<ActivityLivePlayerBinding, LiveViewModel>(), OnChatClickListener,
    IPlayer.OnRenderingStartListener, IPlayer.OnPreparedListener, IPlayer.OnErrorListener,
    SurfaceHolder.Callback, View.OnClickListener {
    private val streamUrl: String by lazy { intent.getStringExtra(URL) ?: "" }
    private val title: String by lazy { intent.getStringExtra(TITLE) ?: "" }
    private val liveRoom: LiveRoomResponse? by lazy { intent.getParcelableExtra(LIVE_ROOM_DATA) }
    private val mAliPlayer: AliPlayer by lazy {
        AliPlayerFactory.createAliPlayer(appContext).apply {
            isAutoPlay = false
            // 设置直播不缓存
            setOnRenderingStartListener(this@LivePlayerActivity)
            setOnPreparedListener(this@LivePlayerActivity)
            setOnErrorListener(this@LivePlayerActivity)
        }
    }

    companion object {
        private const val URL = "key_url"
        private const val TITLE = "key_title"
        private const val LIVE_ROOM_DATA = "live_room_data"

        @JvmStatic
        fun launch(context: Context, liveRoomResponse: LiveRoomResponse) {
            val intent = Intent(context, LivePlayerActivity::class.java)
            intent.putExtra(LIVE_ROOM_DATA, liveRoomResponse)
            context.startActivity(intent)
        }
    }

    override val userBaseTitle: Boolean
        get() = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun inflateBinding(): ActivityLivePlayerBinding {
        return ActivityLivePlayerBinding.inflate(layoutInflater)
    }

    override fun initialize(savedInstanceState: Bundle?) {
        collectEvent()
        initEvent()
        collectPageState()
        binding.surfaceView.holder.addCallback(this)
        showChatLayout()
        fetchLiveStatus()
        fetchCover()
    }

    override fun initEvent() {
        binding.ivClose.setOnClickListener(this)
    }

    private fun fetchLiveRoom() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomList)
        }
    }

    private fun fetchLiveGood() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveGood)
        }
    }

    /**
     * 获取直播间其他信息
     */
    private fun fetchLiveRoomOtherInfo() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.EnterRoom)
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomNum)
        }
    }

    private fun fetchLiveRoomTopGood(liveId: Int?) {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveTopGood(liveId))
        }
    }

    private var liveNumJob: Job? = null
    private fun startTickerRequest() {
        liveNumJob?.cancel()
        liveNumJob = tickFlow(10000L) {
            lifecycleScope.launchWhenCreated {
                viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomNum)
            }
        }
    }

    private fun cancelTimer() {
        liveNumJob?.cancel()
    }

    private fun preparePlay(pullUrl: String?) {
        if (pullUrl.isNullOrEmpty()) {
            return
        }
        val config = mAliPlayer.config
        config.mEnableLocalCache = false
        config.mMaxDelayTime = 1000
        config.mHighBufferDuration = 100
        config.mStartBufferDuration = 100
        config.mEnableSEI = true
        mAliPlayer.config = config
        if (!isFoldExpandStatus()) {
            mAliPlayer.scaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FILL
        } else {
            mAliPlayer.scaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FIT

        }
        val source = UrlSource()
        source.uri = pullUrl
        mAliPlayer.setDataSource(source)
        mAliPlayer.prepare()
        mAliPlayer.start()

    }

    private fun showLive(liveRoomResponse: LiveRoomResponse) {
        binding.tvRoomName.text = liveRoomResponse.liveRoomName
        preparePlay(liveRoomResponse.pullUrl)
        showLiveView()
    }

    private fun showLiveView() {
        binding.surfaceView.visibility = View.VISIBLE
        binding.ivCover.visibility = View.GONE
    }

    private fun releasePlay() {
        stopPlay()
        mAliPlayer.setSurface(null)
        mAliPlayer.release()
    }

    private fun stopPlay() {
        mAliPlayer.stop()
    }

    private fun collectPageState() {
        viewModel.state.observeEvent(this) {
            when (it) {
                is LivePlayerState.HasLiveRoom -> {
                    fetchLiveRoomOtherInfo()
                    fetchLiveRoomTopGood(it.liveRoom.liveId)
                    startTickerRequest()
                    showLive(it.liveRoom)


                }

                LivePlayerState.NoLiveRoom -> {
                    hideLive()
                }

                is LivePlayerState.FetchGoodSuccess -> {
                    chatDialog?.setGoodList(it.list)
                }

                is LivePlayerState.FetchOnlineNumSuccess -> {
                    binding.tvNum.text = "在线观看 ${it.num} 人"
                }

                is LivePlayerState.FetchTopGoodSuccess -> {
                    chatDialog?.showTopGood(it.good)
                }

                is LivePlayerState.OnExitRoom -> {
                    finish()
                }

                is LivePlayerState.OtherSettingValue -> {
                    binding.ivCover.load(this, it.value)
                }
            }
        }
    }
    private fun fetchCover(){
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.OtherSettingValue)
        }
    }
    private fun collectEvent() {
        LiveEventBus.get<Boolean>(BusConstants.LIVE_STATUS_EVENT).observe(this) {
            if (it) {
                fetchLiveRoom()
            } else {
                // 直播间结束了
                ToastUtils.show("")
                hideLive()
            }
        }
        LiveEventBus.get<PushTopGoodModel>(BusConstants.LIVE_TOP_GOOD).observe(this) {
            if (it.liveId != null && it.goodId != null) {
                fetchLiveRoomTopGood(it.liveId)
            }
        }
//        LiveEventBus.get<Boolean>(BusConstants.LIVE_TOP_GOOD_STOP).observe(this) {
//            if (it&&viewModel.currentLiveItem!=null){
//                fetchLiveRoomTopGood(viewModel.currentLiveItem?.liveId)
//            }
//        }
    }

    private fun hideLive() {
        binding.ivCover.visibility = View.VISIBLE
        releasePlay()
        chatDialog?.onLiveStop()
        cancelTimer()

    }


    private var chatDialog: ChatDialogFragment? = null
    private fun showChatLayout() {
        chatDialog = ChatDialogFragment.newInstance()
        chatDialog?.setListener(this)
        chatDialog?.show(supportFragmentManager, "ChatDialogFragment")
    }




    override fun onClick(v: View?) {
        when (v?.id) {
            binding.ivClose.id -> {
                logD("按钮返回")
                onBackPressed()
            }
        }
    }

    private fun exitRoom() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.ExitRoom)
        }

    }


    override fun onGoodsClick() {
        fetchLiveGood()

    }

    override fun getGoodsList() {

    }



    private fun fetchLiveStatus() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomDetail(liveRoom?.pullId))
        }
    }

    override fun onPrepared() {
        // 预加载完成
        logD("阿里云播放器加载预加载完成")
        //准备完毕后延迟显示，防止闪黑屏
        lifecycleScope.launchWhenCreated {
            delay(200)
            binding.surfaceView.visibility = View.VISIBLE
        }
    }

    override fun onError(p0: ErrorInfo?) {
        logD("阿里云播放器播放出错了=${gson.toJson(p0)}")
        // 播放出错了查询一下直播间状态
        fetchLiveStatus()
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        mAliPlayer.setSurface(holder.surface)
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        mAliPlayer.surfaceChanged()
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        mAliPlayer.setSurface(null)
    }

    override fun onRenderingStart() {

    }
    override fun onBackPressed() {
        exitRoom()
    }
    override fun onPause() {
        stopPlay()
        super.onPause()

    }
    override fun onResume() {
        super.onResume()
        // 查询这个直播间状态,这个时候表示有直播间的，但是直播间状态是异常的 ，所以要查询是否正常 当前没有直播
        if (viewModel.currentLiveItem != null && viewModel.currentLiveItem?.liveStatus != 1) {
            fetchLiveStatus()
            return
        }
        preparePlay(viewModel.currentLiveItem?.pullUrl)
    }

    override fun onDestroy() {
        super.onDestroy()
        releasePlay()
        chatDialog = null
        liveNumJob?.cancel()
        liveNumJob = null

    }
}
